package com.unlcn.ils.wms.backend.service.operation.impl;

import cn.huiyunche.commons.domain.PageVo;
import cn.huiyunche.commons.exception.BusinessException;
import com.google.common.collect.Maps;
import com.unlcn.ils.wms.backend.enums.SendStatusEnum;
import com.unlcn.ils.wms.backend.enums.WebServiceWhcodeEnum;
import com.unlcn.ils.wms.backend.enums.WhCodeEnum;
import com.unlcn.ils.wms.backend.enums.WmsOutOfStorageSendStatus;
import com.unlcn.ils.wms.backend.service.operation.WmsJmOutOfStorageOperationService;
import com.unlcn.ils.wms.base.dto.WmsJMOutOfStorageOperationResultListDTO;
import com.unlcn.ils.wms.base.dto.WmsJmOutOfStorageExcpOperationDTO;
import com.unlcn.ils.wms.base.mapper.extmapper.WmsOutOfStorageExtMapper;
import com.unlcn.ils.wms.base.mapper.sys.SysUserMapper;
import com.unlcn.ils.wms.base.model.junmadcs.WmsOutOfStorage;
import com.unlcn.ils.wms.base.model.junmadcs.WmsOutOfStorageExcp;
import com.unlcn.ils.wms.base.model.sys.SysUser;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;

/**
 * 用于君马运维的出入库业务处理(主要是数据重发)
 */
@Service
public class WmsJmOutOfStorageOperationServiceImpl implements WmsJmOutOfStorageOperationService {
    private Logger logger = LoggerFactory.getLogger(getClass());
    private WmsOutOfStorageExtMapper wmsOutOfStorageExtMapper;

    @Autowired
    public void setWmsOutOfStorageExtMapper(WmsOutOfStorageExtMapper wmsOutOfStorageExtMapper) {
        this.wmsOutOfStorageExtMapper = wmsOutOfStorageExtMapper;
    }

    /**
     * 查询出入库接口发送dcs/sap列表
     *
     * @param dto 参数封装
     */
    @Override
    public HashMap<String, Object> listOutOfStorageExcp(WmsJmOutOfStorageExcpOperationDTO dto) throws Exception {
        logger.info("WmsJmOutOfStorageOperationServiceImpl.listOutOfStorageExcp");
        if (dto == null)
            throw new BusinessException("参数不能为空!");
        String whCode = dto.getWhCode();
        if (StringUtils.isBlank(whCode))
            throw new BusinessException("仓库code不能为空!");
        if (!(WhCodeEnum.JM_CS.getValue().equals(whCode) || WhCodeEnum.JM_XY.getValue().equals(whCode))) {
            throw new BusinessException("该仓库不支持此操作!");
        }
        HashMap<String, Object> params = Maps.newHashMap();
        getParams(dto, whCode, params);
        List<WmsJMOutOfStorageOperationResultListDTO> list = wmsOutOfStorageExtMapper.listOutOfStorageExcps(params);
        list.forEach(v -> {
            //dcs失败的数据,最终是否失败
            if (WmsOutOfStorageSendStatus.SEND_FAILED.getValue().equals(v.getSendStatus())) {
                if (StringUtils.isBlank(v.getFinalDcsStatus())) {
                    v.setFinalDcsStatus(SendStatusEnum.NOT_FINAL.getValue());
                } else {
                    v.setFinalDcsStatus(SendStatusEnum.FINAL_FAIL.getValue());
                }
            }
            //发送dcs成功
            if (SendStatusEnum.SEND_SUCCESS.getValue().equals(v.getSendStatus())) {
                v.setFinalDcsStatus(SendStatusEnum.FINAL_SUCCESS.getValue());
            }
            //未发送
            if (SendStatusEnum.SEND_INIT.getValue().equals(v.getSendStatus())) {
                v.setFinalDcsStatus(SendStatusEnum.NOT_SEND.getValue());
            }
            //sap
            if (SendStatusEnum.SEND_FAILED.getValue().equals(v.getSendStatusSap())) {
                if (StringUtils.isBlank(v.getFinalSapStatus())) {
                    v.setFinalSapStatus(SendStatusEnum.NOT_FINAL.getValue());
                } else {
                    v.setFinalSapStatus(SendStatusEnum.FINAL_FAIL.getValue());
                }
            }
            if (SendStatusEnum.SEND_SUCCESS.getValue().equals(v.getSendStatusSap())) {
                v.setFinalSapStatus(SendStatusEnum.FINAL_SUCCESS.getValue());
            }
            if (SendStatusEnum.SEND_INIT.getValue().equals(v.getSendStatusSap())) {
                v.setFinalSapStatus(SendStatusEnum.NOT_SEND.getValue());
            }
        });
        int count = wmsOutOfStorageExtMapper.countOutOfStorageExcps(params);
        PageVo pageVo = new PageVo();
        pageVo.setPageSize(dto.getPageSize());
        pageVo.setOrder(dto.getOrder());
        pageVo.setTotalRecord(count);
        pageVo.setPageNo(dto.getPageNo());
        HashMap<String, Object> resultMap = Maps.newHashMap();
        resultMap.put("data", list);
        resultMap.put("pageVo", pageVo);
        return resultMap;
    }

    private SysUserMapper sysUserMapper;

    @Autowired
    public void setSysUserMapper(SysUserMapper sysUserMapper) {
        this.sysUserMapper = sysUserMapper;
    }

    /**
     * 更新重发出入库数据到dcs
     *
     * @param dto 参数封装
     * @throws Exception 异常
     */
    @Override
    public void updateSendToDCSAgain(WmsJmOutOfStorageExcpOperationDTO dto) throws Exception {
        logger.info("WmsJmOutOfStorageOperationServiceImpl.updateSendToDCSAgain params:{}", dto);
        if (dto == null)
            throw new BusinessException("参数不能为空!");
        String whCode = dto.getWhCode();
        String userId = dto.getUserId();
        String dataIds = dto.getDataIds();
        if (StringUtils.isBlank(whCode))
            throw new BusinessException("仓库code不能为空!");
        if (!(WhCodeEnum.JM_CS.getValue().equals(whCode) || WhCodeEnum.JM_XY.getValue().equals(whCode))) {
            throw new BusinessException("该仓库不支持此操作!");
        }
        if (StringUtils.isBlank(dataIds))
            throw new BusinessException("请选择数据,进行后续的重传!");
        if (StringUtils.isBlank(userId))
            throw new BusinessException("用户id不能为空!");
        SysUser sysUser = sysUserMapper.selectByPrimaryKey(Integer.valueOf(userId));
        if (sysUser == null)
            throw new BusinessException("未查询到对应的用户信息");
        String[] ids_str = dataIds.split(",");
        List<String> ids = Arrays.asList(ids_str);
        List<WmsOutOfStorageExcp> excps = wmsOutOfStorageExtMapper.selectExcpListByIds(ids);
        if (CollectionUtils.isNotEmpty(excps)) {
            if (ids.size() != excps.size()) {
                throw new BusinessException("选择的数据种和查询异常数据条数不一致");
            }
            excps.forEach(v -> {
                if (!SendStatusEnum.SEND_FAILED.getValue().equals(v.getDcsSendStatus())) {
                    throw new BusinessException("车架号:" + v.getSernr() + "未发送DCS失败,不能进行重发");
                }
                if (StringUtils.isBlank(v.getDcsFinalStatus())) {
                    throw new BusinessException("车架号:" + v.getSernr() + "未最终确定发送DCS状态,请稍后处理");
                }
            });
        }

        HashMap<String, Object> params = Maps.newHashMap();
        params.put("username", sysUser.getName());
        params.put("list", ids);
        wmsOutOfStorageExtMapper.updateSendDcsAgainBatch(params);
    }

    /**
     * 更新重发sap系统
     *
     * @param dto 参数封装
     * @throws Exception 异常
     */
    @Override
    public void updateSendToSapAgain(WmsJmOutOfStorageExcpOperationDTO dto) throws Exception {
        logger.info("WmsJmOutOfStorageOperationServiceImpl.updateSendToSapAgain params:{}", dto);
        if (dto == null)
            throw new BusinessException("参数不能为空!");
        String whCode = dto.getWhCode();
        String userId = dto.getUserId();
        String dataIds = dto.getDataIds();
        if (StringUtils.isBlank(whCode))
            throw new BusinessException("仓库code不能为空!");
        if (!(WhCodeEnum.JM_CS.getValue().equals(whCode) || WhCodeEnum.JM_XY.getValue().equals(whCode))) {
            throw new BusinessException("该仓库不支持此操作!");
        }
        if (StringUtils.isBlank(dataIds))
            throw new BusinessException("请选择数据,进行后续的重传!");
        if (StringUtils.isBlank(userId))
            throw new BusinessException("用户id不能为空!");
        SysUser sysUser = sysUserMapper.selectByPrimaryKey(Integer.valueOf(userId));
        if (sysUser == null)
            throw new BusinessException("未查询到对应的用户信息");
        String[] ids_str = dataIds.split(",");
        List<String> ids = Arrays.asList(ids_str);
        List<WmsOutOfStorageExcp> excps = wmsOutOfStorageExtMapper.selectExcpListByIds(ids);
        if (CollectionUtils.isNotEmpty(excps)) {
            if (ids.size() != excps.size()) {
                throw new BusinessException("选择的数据种和查询异常数据条数不一致");
            }
            excps.forEach(v -> {
                if (!SendStatusEnum.SEND_FAILED.getValue().equals(v.getSendStatusSap())) {
                    throw new BusinessException("车架号:" + v.getSernr() + "未发送SAP失败,不能进行重发");
                }
                if (StringUtils.isBlank(v.getSapFinalStatus())) {
                    throw new BusinessException("车架号:" + v.getSernr() + "未最终确定发送SAP状态,请稍后处理");
                }
            });
        }

        HashMap<String, Object> params = Maps.newHashMap();
        params.put("username", sysUser.getName());
        params.put("list", ids);
        wmsOutOfStorageExtMapper.updateSendSapAgainBatch(params);
    }

    /**
     * 手动调整发送sap结果为成功
     *
     * @param dto 参数封装
     * @throws Exception 异常
     */
    @Override
    public void updateSendToSapSuccess(WmsJmOutOfStorageExcpOperationDTO dto) throws Exception {
        logger.info("WmsJmOutOfStorageOperationServiceImpl.updateSendToSapSuccess params:{}", dto);
        if (dto == null)
            throw new BusinessException("参数不能为空!");
        String whCode = dto.getWhCode();
        String userId = dto.getUserId();
        String dataIds = dto.getDataIds();
        if (StringUtils.isBlank(whCode))
            throw new BusinessException("仓库code不能为空!");
        if (!(WhCodeEnum.JM_CS.getValue().equals(whCode) || WhCodeEnum.JM_XY.getValue().equals(whCode))) {
            throw new BusinessException("该仓库不支持此操作!");
        }
        if (StringUtils.isBlank(dataIds))
            throw new BusinessException("请选择数据,进行后续的重传!");
        if (StringUtils.isBlank(userId))
            throw new BusinessException("用户id不能为空!");
        SysUser sysUser = sysUserMapper.selectByPrimaryKey(Integer.valueOf(userId));
        if (sysUser == null)
            throw new BusinessException("未查询到对应的用户信息");
        String[] ids_str = dataIds.split(",");
        List<String> ids = Arrays.asList(ids_str);
        List<WmsOutOfStorage> list = wmsOutOfStorageExtMapper.selectStorageListByIds(ids);
        if (CollectionUtils.isNotEmpty(list)) {
            list.forEach(v -> {
                if (SendStatusEnum.SEND_SUCCESS.getValue().equals(v.getSendStatusSap())) {
                    throw new BusinessException("车架号:" + v.getSernr() + "发送SAP状态为成功,不能进行该操作");
                }
            });
        }
        HashMap<String, Object> params = Maps.newHashMap();
        params.put("username", sysUser.getName());
        params.put("list", ids);
        params.put("msg", "创建物料凭证成功!--web页面手动");
        params.put("success", SendStatusEnum.SEND_SUCCESS.getValue());
        wmsOutOfStorageExtMapper.updateSendSapResultSuccess(params);
    }

    /**
     * 手动调整发送dcs结果为成功
     *
     * @param dto 参数封装
     * @throws Exception 异常
     */
    @Override
    public void updateDcsToSuccess(WmsJmOutOfStorageExcpOperationDTO dto) throws Exception {
        logger.info("WmsJmOutOfStorageOperationServiceImpl.updateDcsToSuccess params:{}", dto);
        if (dto == null)
            throw new BusinessException("参数不能为空!");
        String whCode = dto.getWhCode();
        String userId = dto.getUserId();
        String dataIds = dto.getDataIds();
        if (StringUtils.isBlank(whCode))
            throw new BusinessException("仓库code不能为空!");
        if (!(WhCodeEnum.JM_CS.getValue().equals(whCode) || WhCodeEnum.JM_XY.getValue().equals(whCode))) {
            throw new BusinessException("该仓库不支持此操作!");
        }
        if (StringUtils.isBlank(dataIds))
            throw new BusinessException("请选择数据,进行后续的重传!");
        if (StringUtils.isBlank(userId))
            throw new BusinessException("用户id不能为空!");
        SysUser sysUser = sysUserMapper.selectByPrimaryKey(Integer.valueOf(userId));
        if (sysUser == null)
            throw new BusinessException("未查询到对应的用户信息");
        String[] ids_str = dataIds.split(",");
        List<String> ids = Arrays.asList(ids_str);
        List<WmsOutOfStorage> list = wmsOutOfStorageExtMapper.selectStorageListByIds(ids);
        if (CollectionUtils.isNotEmpty(list)) {
            list.forEach(v -> {
                if (SendStatusEnum.SEND_SUCCESS.getValue().equals(v.getSendStatus())) {
                    throw new BusinessException("车架号:" + v.getSernr() + "发送DCS状态为成功,不能进行该操作");
                }
            });
        }
        HashMap<String, Object> params = Maps.newHashMap();
        params.put("username", sysUser.getName());
        params.put("list", ids);
        params.put("msg", "创建物料凭证成功!--web页面手动");
        params.put("success", SendStatusEnum.SEND_SUCCESS.getValue());
        wmsOutOfStorageExtMapper.updateSendDcsResultToSuccess(params);

    }

    private void getParams(WmsJmOutOfStorageExcpOperationDTO dto, String whCode, HashMap<String, Object> params) {
        params.put("start", dto.getStartIndex());
        params.put("end", dto.getPageSize());
        params.put("orderBy", StringUtils.isNotBlank(dto.getOrder()) ? dto.getOrder() : " a.DATA_ID desc");
        params.put("vin", dto.getVin());
        params.put("action", dto.getZaction());
        //转换状态的值
        if (StringUtils.isNotBlank(dto.getSendDcsStatus())) {
            switch (dto.getSendDcsStatus()) {
                case "40":
                    dto.setSendDcsStatus(SendStatusEnum.SEND_INIT.getValue());
                    break;
                case "30":
                    dto.setSendDcsStatus(SendStatusEnum.SEND_FAILED.getValue());
                    params.put("finalDCSStatus", "is null");
                    break;
                case "20":
                    dto.setSendDcsStatus(SendStatusEnum.SEND_FAILED.getValue());
                    params.put("finalDCSStatus", "is not null");
                    break;
                case "10":
                    dto.setSendDcsStatus(SendStatusEnum.SEND_SUCCESS.getValue());
                    break;
            }
        }

        if (StringUtils.isNotBlank(dto.getSendSapStatus())) {
            switch (dto.getSendSapStatus()) {
                case "40":
                    dto.setSendSapStatus(SendStatusEnum.SEND_INIT.getValue());
                    break;
                case "30":
                    dto.setSendSapStatus(SendStatusEnum.SEND_FAILED.getValue());
                    params.put("finalSAPStatus", "is null");
                    break;
                case "20":
                    dto.setSendSapStatus(SendStatusEnum.SEND_FAILED.getValue());
                    params.put("finalSAPStatus", "is not null");
                    break;
                case "10":
                    dto.setSendSapStatus(SendStatusEnum.SEND_SUCCESS.getValue());
                    break;
            }
        }

        params.put("sendDcsStatus", StringUtils.isNotBlank(dto.getSendDcsStatus()) ?
                dto.getSendDcsStatus() : WmsOutOfStorageSendStatus.SEND_FAILED.getValue());
        params.put("sendSapStatus", StringUtils.isNotBlank(dto.getSendSapStatus()) ?
                dto.getSendSapStatus() : WmsOutOfStorageSendStatus.SEND_FAILED.getValue());
        switch (whCode) {
            case "JM_CS":
                whCode = WebServiceWhcodeEnum.CS01.getValue();
                break;
            case "JM_XY":
                whCode = WebServiceWhcodeEnum.XY01.getValue();
        }
        params.put("whCode", whCode);
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        String st_str = dto.getStartTime();
        String ed_str = dto.getEndTime();
        try {
            if (StringUtils.isNotBlank(st_str)) {
                st_str = st_str + " 00:00:00";
                params.put("startTime", sdf.parse(st_str));
            }
            if (StringUtils.isNotBlank(ed_str)) {
                ed_str = ed_str + " 23:59:59";
                params.put("endTime", sdf.parse(ed_str));
            }
        } catch (ParseException e) {
            throw new BusinessException("日期格式转换错误");
        }
    }
}
